package com.zwp.base.paging

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.OnRebindCallback
import androidx.databinding.ViewDataBinding
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import me.tatarka.bindingcollectionadapter2.ItemBinding
import java.lang.Exception


class BindingRecyclerViewAdapter<T : Any>(diffItemCallback: DiffUtil.ItemCallback<T>) :
    PagingDataAdapter<T, BindingRecyclerViewAdapter.BindingViewHolder<T>>(diffItemCallback) {

    companion object {
        val DATA_INVALIDATION = Object()
    }

    var viewHolderFactory: ViewHolderFactory<T>? = null

    var recyclerView: RecyclerView? = null

    var inflater: LayoutInflater? = null

    var itemBinding: ItemBinding<T>? = null
        get() {
            requireNotNull(field) { "itemBinding == null" }
            return field
        }

    fun onCreateBinding(inflater: LayoutInflater, layoutId: Int, parent: ViewGroup) =
        DataBindingUtil.inflate<ViewDataBinding>(inflater, layoutId, parent, false)

    override fun onBindViewHolder(holder: BindingViewHolder<T>, position: Int) {
        holder.bindTo(itemBinding!!.variableId(), getItem(position)!!)
    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingViewHolder<T> {
        if (inflater == null) {
            inflater = LayoutInflater.from(parent.context)
        }

        return onCreateBinding(inflater!!, viewType, parent).let {
            onCreateViewHolder(it)
        }
    }



    override fun getItemViewType(position: Int): Int {
        itemBinding!!.onItemBind(position, getItem(position))
        return itemBinding!!.layoutRes()
    }

    fun onCreateViewHolder(binding: ViewDataBinding) =
        viewHolderFactory?.createViewHolder(binding) ?: BindingViewHolder(binding)


    class BindingViewHolder<T>(val binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root) {

        fun bindTo(id: Int, item: T) {
            binding.setVariable(id, item)
            binding.executePendingBindings()
        }
    }

    interface ViewHolderFactory<T> {
        fun createViewHolder(binding: ViewDataBinding): BindingViewHolder<T>
    }

}